home *** CD-ROM | disk | FTP | other *** search
/ Utilities Professional 1-1500 / Utilities Professional 1-1500 (1994)(WPD)[!].iso / 07511000 / var0784.dms / var0784.adf / PopCLI4 / pm.c < prev    next >
C/C++ Source or Header  |  1978-01-24  |  17KB  |  565 lines

  1. /*
  2.    COMPILE WITH:
  3.  
  4.  lc1 -b0 -cfiks -d2 -r -rr -j121i -oQUAD:pm.q pm.c
  5.  go  quad:pm.q
  6.  lc2 -v -opm.o quad:pm.q
  7.  
  8. Gets a CXERR 26, Line: 155 out of LC2.
  9. My LC1 and LC2 are both V5.01. Needs AREXX include files.
  10. Commenting out the if on lines 99-102 will cause it to work.
  11. */
  12.  
  13. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  14. /* |_o_o|\\ Copyright (c) 1986 The Software Distillery.  All Rights Reserved */
  15. /* |. o.| || This program may not be distributed without the permission of   */
  16. /* | .  | || the authors.                                                    */
  17. /* | o  | ||    Dave Baker     Ed Burnette  Stan Chow    Jay Denebeim        */
  18. /* |  . |//     Gordon Keener  Jack Rouse   John Toebes  Doug Walker         */
  19. /* ======          BBS:(919)-471-6436      VOICE:(919)-469-4210              */ 
  20. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  21. /*
  22.  * VERY loosely based on the input.device example by Rob Peck, 12/1/85
  23.  */
  24.  
  25. #include "popcli.h"
  26. #include "popbug.h"
  27. #include "cback.h"
  28. #include <rexx/storage.h>
  29.  
  30.  
  31. #ifdef BUGMACROS
  32. #define __BugWindow (*(BPTR *)"BUG") /* 4 bytes, big enuf for a BPTR */
  33. #endif
  34.  
  35. /************************************************************************/
  36. /* the main program to do the popcli stuff                              */
  37. /************************************************************************/
  38.  
  39. #undef global   /* Since it really is local in this routine */
  40.  
  41. void _main()
  42.    {
  43.    struct cbackstr     *cback;
  44.  
  45.    struct MsgPort      *port;
  46.    int                 stay = 0;
  47.    int                 shutdown;
  48.    short               timeout;
  49.    struct OURMSG       *msg;
  50.    register CommandBlock *cb;
  51.    int                 key;
  52.    struct Process      *us;
  53.  
  54.    BPTR  nullfh;
  55.    ULONG sig, portsig, timersig;
  56.    struct timerequest *timerreq;
  57.    struct MsgPort     *timerport;
  58.    struct MsgPort     *inputDevPort;
  59.    struct IOStdReq    *inputRequestBlock;
  60.    struct Interrupt    handlerStuff;
  61.    GLOBAL_DATA         global;
  62.    struct Process     *SyncProcess;
  63.    int                 SyncSignal;
  64.    char               *cmd;
  65.    int                 cmdlen;
  66.    struct RexxMsg     *amsg;
  67.    struct OURMSG       pmsg;   /* for AREXX message parsing */
  68.  
  69.    int                 rc;
  70.  
  71.    memset( (char *)&global, 0, sizeof(global) );
  72.    
  73.    DOSBase = (struct DosBase *)OpenLibrary("dos.library",0);
  74.  
  75.    global.blanksignum  = -1;
  76.    timerreq            = NULL;
  77.    timerport           = NULL;
  78.    inputDevPort        = NULL;
  79.    inputRequestBlock   = NULL;
  80.    msg                 = NULL;
  81.  
  82.    timeout             = DEFTIME;
  83.  
  84.    /* Fetch our arguments from the wild blue yonder */
  85.    us = (struct Process *)FindTask(0);
  86.    us->pr_ConsoleTask = NULL; 
  87.    WaitPort( &(us->pr_MsgPort) );
  88.    cback = (struct cbackstr *)GetMsg( &(us->pr_MsgPort) );
  89.  
  90.    global.stdout = cback->stdout;
  91.  
  92.    /* Bit of a kludge... remove the trailing "\n" so we don't have to */
  93.    /* muck with it in popparse(). Put a null on, too; and we can't    */
  94.    /* overwrite because there may not be enough room.                 */
  95.    cmdlen = cback->cmdlen;
  96.    cmd = AllocMem( cmdlen + 1, 0 );
  97.    memcpy( cmd, cback->cmd, cmdlen );
  98. /* !!!!! IF YOU COMMENT OUT THIS IF STATEMENT, THE CXERR 26 GOES AWAY! */
  99.    if (cmd[cmdlen-1] == '\n')
  100.       cmd[cmdlen-1] = '\0';
  101.    else
  102.       cmd[cmdlen] = '\0';
  103.  
  104.    SyncProcess = cback->SyncProcess;
  105.    SyncSignal = cback->SyncSignal;
  106.  
  107.    FreeMem( (char *)cback, cback->msgpart.mn_Length );
  108.  
  109.    /* now see if we are already installed */
  110.    if ((port = FindPort(PORTNAME)) == NULL)
  111.       {
  112.       stay = 1; /* remember to hang around when we are done */
  113. #ifdef BUGMACROS
  114.       __BugWindow = Open(BUGWINDOW,MODE_NEWFILE);
  115. #endif
  116.       BUG(("Setting stay to 1 - first time here\n"));
  117.  
  118.       /* not installed, we need to install our own port */
  119.       if ((port = MyCreatePort(&global, PORTNAME)) == NULL)
  120.          goto abort;
  121.  
  122.       /* Tell everybody we're here... */
  123.       popbanner( &global );
  124.       }
  125. #ifdef BUGMACROS
  126.    else
  127.       __BugWindow = Open("*", MODE_OLDFILE);
  128. #endif
  129.  
  130.    /* Save port for handler to use */
  131.    global.execport = port;
  132.  
  133.    /* now send the parameter to the waiting program */
  134.    if ((msg = (struct OURMSG *)
  135.               AllocMem(sizeof(struct OURMSG), MEMF_CLEAR|MEMF_PUBLIC)) == NULL)
  136.       goto abort;
  137.    /* fill in the message information */
  138.    msg->msgpart.mn_Length = sizeof(struct OURMSG);
  139.  
  140.    if (cmd[cmdlen-1] == '\n')
  141.       cmd[cmdlen-1] = '\0';      
  142.  
  143.    rc = popparse( &global, cmd, msg );
  144.  
  145.    /* We're done with the command line */
  146.    FreeMem( cmd, cmdlen+1 );
  147.  
  148.    if (rc == SHUTDOWN)
  149.    {
  150.       /* Print shutting down message */
  151.       poptrailer( &global );
  152.    }
  153.  
  154.    /* Get stack size and stuff from our parent, if we're the server */
  155.    if (stay)
  156.       copyproc( &global, us, SyncProcess );
  157.  
  158.    /* Let the original window go away */
  159.    if (global.stdout)
  160.       Close(global.stdout);
  161.    global.stdout = 0;
  162.  
  163.    /* We got everything, so it's safe to let the parent go away */
  164.    if (SyncSignal != -1)
  165.    {
  166.       Signal((struct Task *)SyncProcess, 1<<SyncSignal);
  167.       SyncSignal = -1;
  168.    }
  169.  
  170.    global.blankscreen = NULL;
  171.    if (stay && msg->interval == 0)
  172.       msg->interval = DEFTIME;
  173.  
  174.    PutMsg(port,(struct Message *)msg);
  175.  
  176.    msg = NULL;
  177.  
  178.    /* If we're told to go away */
  179.    if ((rc == SHUTDOWN) || (rc == LEAVE) || !stay)
  180.    {
  181.       goto abort;
  182.    }
  183.  
  184.    global.noevents = 0;
  185.  
  186.    /* set the input and output streams to 0 so execute doen't complain */
  187.    nullfh = Open("NIL:", MODE_NEWFILE);
  188.  
  189.    if (((inputDevPort = MyCreatePort(&global,NULL)) == NULL)                 ||
  190.  
  191.       ((inputRequestBlock =
  192.           CreateIOReq(&global, inputDevPort, sizeof(struct IOStdReq))) == NULL)     ||
  193.  
  194.       ((timerport = MyCreatePort(&global,NULL)) == NULL)                     ||
  195.  
  196.       ((timerreq  = (struct timerequest *)
  197.           CreateIOReq(&global,timerport, sizeof(struct timerequest))) == NULL) ||
  198.  
  199.       ((global.blanksignum = AllocSignal(-1)) == -1)                       ||
  200.  
  201.       ((GfxBase = (GBasePtr)
  202.                   OpenLibrary("graphics.library", 0)) == NULL)             ||
  203.  
  204.       ((IntuitionBase = (IBasePtr)
  205.                         OpenLibrary("intuition.library", 0)) == NULL)      ||
  206.       OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timerreq, 0)  ||
  207.  
  208.       OpenDevice("input.device",0,(struct IORequest *)inputRequestBlock,0))
  209.  
  210.       goto abort;
  211.  
  212.    handlerStuff.is_Data = (APTR)&global;
  213.    handlerStuff.is_Code = (VOID(*)())myhandler;
  214.    handlerStuff.is_Node.ln_Pri = 51;
  215.  
  216.    timersig            = (1 << timerport->mp_SigBit);
  217.    portsig             = (1 << port->mp_SigBit);
  218.    global.unblanksig   = 1 << global.blanksignum;
  219.  
  220.    inputRequestBlock->io_Command = IND_ADDHANDLER;
  221.    inputRequestBlock->io_Data    = (APTR)&handlerStuff;
  222.  
  223.    DoIO((struct IORequest *)inputRequestBlock);
  224.  
  225.    global.buddy = (struct Task *)us;
  226.  
  227.    QueueTimer(&global, timerreq, TIMEINTERVAL);
  228.  
  229.    /* All other fields in newscreen are 0 */
  230.    global.newscreen.Width    = 320;
  231.    global.newscreen.Height   = 30;
  232.    global.newscreen.Depth    = 1;
  233.    global.newscreen.BlockPen = 1;
  234.    global.newscreen.Type     = CUSTOMSCREEN;
  235.  
  236.    shutdown = 0;
  237.    while(!shutdown)
  238.       {
  239.       sig = Wait( portsig | global.unblanksig | timersig );
  240.  
  241.       /* see if we have anything to do */
  242.       while ((msg = (struct OURMSG *)GetMsg(port)) != NULL)
  243.       {
  244.      if ((msg->msgpart.mn_Node.ln_Name) &&
  245.              !strcmp(msg->msgpart.mn_Node.ln_Name, "REXX"))
  246.      {
  247.         /* we've got an ARexx message to parse. */
  248.         amsg = (struct RexxMsg *)msg;
  249.         rc = popparse( &global, amsg->rm_Args[0], &pmsg );
  250.         amsg->rm_Result1 = (rc == LEAVE) ? 5 : 0;
  251.         amsg->rm_Result2 = 0;
  252.         ReplyMsg( (struct Message *)amsg );
  253.  
  254.             /* So our normal msg processing code can handle it */
  255.         msg = &pmsg;
  256.          }
  257.      else
  258.         amsg = NULL;
  259.  
  260.          /* See which type of message we have */
  261.          switch( msg->type ) {
  262.  
  263.          /*----------------------------------------------------*/
  264.          case MSG_ADDKEY:
  265.             BUG(("*Add Key %d\n", msg->key));
  266.  
  267.             /* Because of parsing, we stick the interval information */
  268.             /* in with the MSG_ADDKEY. There should be a better way  */
  269.             /* to do this.                                           */
  270.             if (msg->interval)
  271.             {
  272.                timeout = msg->interval;
  273.                BUG(("Interval == %d ticks\n", timeout));
  274.             }
  275.  
  276.             /* If we already have defined this key, then we can   */
  277.             /* update its command, else add the key.              */
  278.             cb = global.keytab[msg->key];
  279.  
  280.             if (!cb)
  281.             {
  282.                /* Its not there, we need to add the key */
  283.                if (cb = (CommandBlock *)
  284.                              AllocMem(sizeof(CommandBlock),MEMF_PUBLIC))
  285.                {
  286.  
  287.                   /* Give new key the default command */
  288.                   strcpy(cb->command, DEFCMD);
  289.                   cb->cmdflags = 0;
  290.                   cb->minmem   = msg->minmem;
  291.                   cb->minchip  = msg->minchip;
  292.                   global.keytab[msg->key] = cb;
  293.  
  294.                   BUG((" creating <%d> at 0x%08lx", msg->key, (long)cb));
  295.                }
  296.             }
  297.  
  298.             /* Update the key command, for new or old key */
  299.             if (cb && msg->command[0])
  300.             {
  301.                strcpy(cb->command, msg->command);
  302.                cb->cmdflags = msg->cmdflags;
  303.             }
  304.  
  305. #ifdef BUGMACROS
  306.             if (cb)
  307.                BUG(("  New command = `%s'\n", cb->command));
  308. #endif
  309.             break;
  310.  
  311.          /*----------------------------------------------------*/
  312.          case MSG_DELKEY:
  313.             BUG(("*Delete Key %d\n", msg->key));
  314.  
  315.             cb = global.keytab[msg->key];
  316.         if (cb)
  317.         {
  318.                BUG(("  killing <%d> at 0x%08lx\n", msg->key, (long)cb));
  319.  
  320.                global.keytab[msg->key] = NULL;
  321.                FreeMem( (char *)cb, sizeof(CommandBlock) );
  322.             }
  323.             break;
  324.  
  325.          /*----------------------------------------------------*/
  326.          case MSG_EXECUTE:
  327.             BUG(("*Execute for key %d\n", msg->key));
  328.             cb = global.keytab[msg->key];
  329.  
  330.         if (cb)
  331.         {
  332.                BUG(("   Executing `%s'\n", cb->command));
  333.  
  334.                if (((cb->minmem  == 0) ||
  335.                           ((AvailMem(MEMF_PUBLIC)>>10) > cb->minmem )) &&
  336.                    ((cb->minchip == 0) ||
  337.                           ((AvailMem(MEMF_CHIP  )>>10) > cb->minchip)))
  338.                {
  339.                   if (!(cb->cmdflags & FLAG_NOWB2F))
  340.                      WBenchToFront();
  341.  
  342.                   if (! Execute(cb->command, nullfh, nullfh))
  343.                      DisplayBeep(NULL);
  344.                }
  345.                else
  346.                   DisplayBeep(NULL);
  347.             }
  348.         break;
  349.  
  350.          /*----------------------------------------------------*/
  351.          case MSG_SHUTDOWN:
  352.             BUG(("Shut UP!!\n"));
  353.  
  354.             /* Cause us to drop out of loop when we're thru */
  355.             shutdown = 1;
  356.             break;
  357.  
  358.          /*----------------------------------------------------*/
  359.          case MSG_BLANK:
  360.             if (global.blankscreen == NULL)
  361.             {
  362.                if ( (global.blankscreen = OpenScreen(&global.newscreen)) != NULL)
  363.                {
  364.                   BUG(("Screen OFF!!!!!\n"));
  365.                   SetRGB4(&(global.blankscreen->ViewPort), 0, 0, 0, 0);
  366.                   OFF_DISPLAY
  367.                }
  368.             }
  369.             break;
  370.  
  371.          /*----------------------------------------------------*/
  372.          case MSG_UNBLANK:
  373.             if (global.blankscreen)
  374.             {
  375.                CloseScreen(global.blankscreen);
  376.            ON_DISPLAY
  377.                global.blankscreen = NULL;
  378.                global.noevents = 0;
  379.             }
  380.             break;
  381.  
  382.          /*----------------------------------------------------*/
  383.          case MSG_SETTIME:
  384.             timeout = msg->interval;
  385.             break;
  386.  
  387.          /*----------------------------------------------------*/
  388.          default:
  389.             BUG(("HEY, I got an unknown message at %08lx!!!!!\n", msg));
  390.          }
  391.  
  392.          if (!amsg)
  393.             FreeMem((char *)msg, msg->msgpart.mn_Length);
  394.       }
  395.  
  396.       if ((sig & global.unblanksig) && global.blankscreen)
  397.          {
  398.          BUG(("Screen On\n"));
  399.  
  400.          CloseScreen(global.blankscreen);
  401.      ON_DISPLAY
  402.          global.blankscreen = NULL;
  403.          }
  404.  
  405.       if (sig & timersig)
  406.          {
  407.          /* get rid of the message */
  408.          (void)GetMsg(timerport);
  409.          QueueTimer(&global, timerreq, TIMEINTERVAL);
  410.  
  411.          if ((global.noevents++ >= timeout) && (global.blankscreen == NULL))
  412.             {
  413.             if ( (global.blankscreen = OpenScreen(&global.newscreen)) != NULL)
  414.                {
  415.                BUG(("Screen OFF!!!!!\n"));
  416.                SetRGB4(&(global.blankscreen->ViewPort), 0, 0, 0, 0);
  417.                OFF_DISPLAY
  418.                }
  419.             }
  420.          }
  421.  
  422.       /* Force our screen to front on a regular basis to handle something   */
  423.       /* that might put their stuff in front of us while we are supposed to */
  424.       /* Be blanking the screen.                                            */
  425.       if (global.blankscreen)
  426.          {
  427.          BUG(("Screen still off\n"));
  428. #if 1
  429.          if (((IBasePtr)IntuitionBase)->FirstScreen != global.blankscreen)
  430.             ScreenToFront(global.blankscreen);
  431. #endif
  432.          OFF_DISPLAY
  433.          }
  434.       }
  435.  
  436.    BUG(("Normal POPCLI shutdown beginning...\n"));
  437.  
  438. abort:
  439.  
  440.    if (stay)
  441.       BUG(("In `abort'...\n"));
  442.  
  443.    if (msg) FreeMem((char *)msg, msg->msgpart.mn_Length);
  444.    if (timerreq != NULL)
  445.       {
  446.       if (timerreq->tr_node.io_Device != NULL)
  447.          {
  448.          AbortIO( (struct IORequest *)timerreq );
  449.          CloseDevice((struct IORequest *)timerreq);
  450.          }
  451.       DeleteIOReq(&global, (struct IOStdReq *)timerreq);
  452.       }
  453.  
  454.    if (inputRequestBlock != NULL)
  455.       {
  456.       if (inputRequestBlock->io_Device != NULL)
  457.          {
  458.          inputRequestBlock->io_Command = IND_REMHANDLER;
  459.          inputRequestBlock->io_Data = (APTR)&handlerStuff;
  460.          DoIO((struct IORequest *)inputRequestBlock);
  461.  
  462.          CloseDevice((struct IORequest *)inputRequestBlock);
  463.          }
  464.       DeleteIOReq(&global, inputRequestBlock);
  465.       }
  466.  
  467.    if (timerport != NULL)          MyDeletePort(&global, timerport);
  468.    if (global.blanksignum != -1)   FreeSignal(global.blanksignum);
  469.    if (global.blankscreen != NULL) CloseScreen(global.blankscreen);
  470.    if (IntuitionBase != NULL)      CloseLibrary((struct Library *)IntuitionBase);
  471.    if (GfxBase != NULL)            CloseLibrary((struct Library *)GfxBase);
  472.    if (inputDevPort != NULL)       MyDeletePort(&global, inputDevPort);
  473.    if (stay && (port != NULL))
  474.    {
  475.       /* Empty the port before we trash it */
  476.       while (msg = (struct OURMSG *)GetMsg(port))   /* assign */
  477.          FreeMem( (char *)msg, msg->msgpart.mn_Length );
  478.  
  479.       MyDeletePort(&global, port);
  480.       BUG(("Port gone..."));
  481.    }
  482.  
  483.    if (global.stdout)
  484.       Close(global.stdout);
  485.    if (SyncSignal != -1)
  486.       Signal((struct Task *)SyncProcess, 1<<SyncSignal);
  487.  
  488.    if (stay)
  489.       {
  490.       /* NOTE: "prev" is really used as a "next" here */
  491.       for (key = 0; key < 256; key++)
  492.           {
  493.           if (cb = global.keytab[key])
  494.          {
  495.              BUG(("Deleting key <%d> at 0x%08lx\n", key, cb));
  496.  
  497.              FreeMem( (char *)cb, sizeof(CommandBlock) );
  498.          }
  499.           }
  500.       }
  501.  
  502.    if (nullfh)                     Close(nullfh);
  503.  
  504.    if (stay)
  505.       BUG(("..bye bye"));
  506.  
  507. #ifdef BUGMACROS
  508.    if (stay)
  509.    {
  510.      int paws = 100000;
  511.      while(--paws>0);
  512.      Close(__BugWindow);
  513.    }
  514. #endif
  515.  
  516.    /* Free all our copyproc() stuff, if we were the server */
  517.    if (stay)
  518.       termproc( &global, (struct Process *)FindTask(NULL) );
  519.  
  520.    if (DOSBase)
  521.       CloseLibrary( (struct Library *)DOSBase );
  522. }
  523.  
  524. #ifdef BUGMACROS
  525. #undef DOSBase
  526.  
  527. void __stdargs myprintf(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
  528. char    *fmt;
  529. long    a1, a2, a3, a4, a5, a6, a7, a8, a9;
  530. {
  531.     int            bytes, fmtlen;
  532.     char            buff[512];
  533.     struct DosLibrary    *DOSBase;
  534.  
  535.     if (__BugWindow <= 0) return(0);
  536. #if 0
  537.     fmtlen = strlen(fmt);
  538.     if (fmtlen > 70)
  539.     {
  540.         bytes = sprintf(buff, "BUGMSG: 0x%x, length %d\n", fmt, fmtlen);
  541.         Write(__BugWindow, buff, bytes);
  542.         return(0);
  543.     }
  544.     else
  545.     {
  546.         bytes = sprintf(buff, "BUG(%s)\n", fmt);
  547.         Write(__BugWindow, buff, bytes);
  548.     }
  549. #endif
  550.     
  551.     bytes = sprintf(buff, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
  552.  
  553.     DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0);
  554.  
  555.     if (bytes < sizeof(buff))
  556.         Write(__BugWindow, buff, bytes);
  557.     else
  558.         Write(__BugWindow, "!!! msg too big - prepare to die\n",
  559.                 strlen("!!! msg too big - prepare to die\n"));
  560.  
  561.     CloseLibrary( (struct Library *)DOSBase );
  562.     return(0);
  563. }
  564. #endif
  565.